#include "stdafx.h"
#include "ui_image_viewer.h"

_SSL_BEGIN
_SSUIL_BEGIN

typedef struct _FindUIPresetImageByName
{
	_FindUIPresetImageByName(const tstring &name)
	{
		name_ = name;
	}

	bool operator()(const UIPresetImage &img)
	{
		return name_ == img.image_name;
	}

	tstring name_;
} FindUIPresetImageByName;

UIImageViewer::UIImageViewer()
{
	//
	background_transparent_ = true;
	show_border_ = false;

	//
	// fore_imgs_;
	switch_interval_mseconds_ = 1000;
	// cur_img_;
	cur_img_index_ = 0;
	timer_id_ = 0;
}

UIImageViewer::~UIImageViewer()
{

}

void UIImageViewer::AddImage(const UIPresetImage &img)
{
	UIPresetImages imgs;
	imgs.push_back(img);
	AddImages(imgs);
}

void UIImageViewer::AddImages(const UIPresetImages &imgs)
{
	CsLockGuard(data_lock_);
	fore_imgs_.insert(fore_imgs_.begin(), imgs.begin(), imgs.end());
}

void UIImageViewer::RemoveImage(const UIPresetImage &img)
{
	UIPresetImages imgs;
	imgs.push_back(img);
	RemoveImages(imgs);
}

void UIImageViewer::RemoveImages(const UIPresetImages &imgs)
{
	CsLockGuard(data_lock_);
	for(UIPresetImages::const_iterator iter=imgs.begin(); iter!=imgs.end(); iter++)
	{
		UIPresetImages::iterator iterm = std::find_if(fore_imgs_.begin(), fore_imgs_.end(),
			FindUIPresetImageByName(iter->image_name));
		if(iterm != fore_imgs_.end())
			fore_imgs_.erase(iterm);
	}
}

void UIImageViewer::RemoveImages()
{
	CsLockGuard(data_lock_);
	fore_imgs_.clear();
}

bool UIImageViewer::BeginView()
{
	EndView();
	timer_id_ = SetIDTimer(timer_id_, switch_interval_mseconds_);
	return timer_id_ != 0;
}

void UIImageViewer::EndView()
{
	if(timer_id_ != 0)
	{
		KillIDTimer(timer_id_);
		timer_id_ = 0;
	}
	cur_img_index_ = 0;
}

void UIImageViewer::SetSwitchIntervalMSeconds(unsigned int switch_interval_mseconds /*= 0*/)
{
	switch_interval_mseconds_ = switch_interval_mseconds;
}

void UIImageViewer::SetCurrentImage(const UIPresetImage &img)
{
	CsLockGuard(data_lock_);
	cur_img_ = img;
	SmartSetNeedUpdate(true);
}

void UIImageViewer::OnRenderForeground(const UIRenderContext &rc)
{
	if(timer_id_ != 0)
		return;
	DrawCurrentImage(rc);
}

bool UIImageViewer::ApplyAttributes(IUIBuilderInterface *ui_builder, 
	IUIXMLDocumentInterface *xml_document, UIXmlNode node)
{
	if(!__super::ApplyAttributes(ui_builder, xml_document, node))
		return false;

	UIXmlAttribute attribute = NULL;

	//
	attribute = xml_document->FirstAttribute(node, "fore_images");
	if(attribute != NULL)
	{
		tstrings pairs = str_split(auto_cvt(xml_document->AttributeValue(attribute)).c_tstr(),
			_T('|'));
		UIPresetImages imgs;
		for(tstrings::iterator iter=pairs.begin(); iter!=pairs.end(); iter++)
		{
			UIPresetImage img;
			if(UIValueParseUtil::ParseImage(auto_cvt(*iter).c_astr(), img) == 1)
			{
				imgs.push_back(img);
			}
		}
		AddImages(imgs);
	}

	attribute = xml_document->FirstAttribute(node, "switch_interval");
	if(attribute != NULL)
	{
		int n = 0;
		if(UIValueParseUtil::ParseInt(xml_document->AttributeValue(attribute), n) == 1)
		{
			SetSwitchIntervalMSeconds(n);
		}
	}

	attribute = xml_document->FirstAttribute(node, "current_image");
	if(attribute != NULL)
	{
		UIPresetImage img;
		if(UIValueParseUtil::ParseImage(xml_document->AttributeValue(attribute), img) == 1)
		{
			SetCurrentImage(img);
		}
	}

	return true;
}

void UIImageViewer::OnTimerCommonCB(unsigned int timer_id)
{
	__super::OnTimerCommonCB(timer_id);

	scoped_ref_ptr<IUIManagerInterface> win_man = GetWindowManager();
	if(win_man == NULL)
		return;
	scoped_ref_ptr<IUIWindowBgCanvasInterface> canvas = win_man->GetBackgroundBgCanvas();
	if(canvas == NULL)
		return;

	if(timer_id == timer_id_)
	{
		CsLockGuard(data_lock_);
		if(cur_img_index_ < 0 || cur_img_index_ >= fore_imgs_.size())
			cur_img_index_ = 0;
		cur_img_index_++;
		if(cur_img_index_ >= fore_imgs_.size())
			cur_img_index_ = 0;
		if(fore_imgs_.size() > 0)
			cur_img_ = fore_imgs_[cur_img_index_];
		else
			cur_img_.image_name.clear();

		UIRenderStruct rs;
		rs.type = kDCTypeForOnlyAnimation;
		rs.dct_4onlyanimation_parameters.invalidate_rt = GetVisiblePositionOnClient();
		void *dc = canvas->BeginRender(rs);

		UIRenderContext render_ctx;
		render_ctx.visible_pos_on_client = GetVisiblePositionOnClient();

		render_ctx.wm = GetWindowManager();
		if(render_ctx.wm == NULL)
			return;
		render_ctx.rr = render_ctx.wm->GetResourceRener();
		if(render_ctx.rr == NULL)
			return;

		render_ctx.dc = dc;
		render_ctx.clip_rt = render_ctx.visible_pos_on_client;
		render_ctx.pos_on_client = GetPositionOnClient();
		render_ctx.client_pos_on_client = GetClientPositionOnClient();
		render_ctx.visible_client_pos_on_client = GetVisibleClientPositionOnClient();
		DrawCurrentImage(render_ctx);
		canvas->EndRender(dc);
	}
}

int UIImageViewer::GetControlAutoWidth()
{
	int ret = __super::GetControlAutoWidth();
	if(ret > 0)
		return ret;

	CsLockGuard(data_lock_);
	if(fore_imgs_.size() == 0)
		return 0;

	return CheckPreseImageSize(fore_imgs_[0]).cx;
}

int UIImageViewer::GetControlAutoHeight()
{
	int ret = __super::GetControlAutoHeight();
	if(ret > 0)
		return ret;

	CsLockGuard(data_lock_);
	if(fore_imgs_.size() == 0)
		return 0;

	return CheckPreseImageSize(fore_imgs_[0]).cy;
}

void UIImageViewer::DrawCurrentImage(const UIRenderContext &rc)
{
	UIPresetImage img;

	{
		CsLockGuard(data_lock_);
		img = cur_img_;
		if(img.image_name.empty() && fore_imgs_.size() > 0)
		{
			img = fore_imgs_[0];
		}
	}

	UIPresetImageInfo img_info;
	if(!rc.rr->CheckPresetImageInfo(img, img_info))
		return;

	UIRect rt_src = img.image_src_rect;
	if(rt_src.Width() <= 0)
	{
		rt_src.left = 0;
		rt_src.right = img_info.cx;
	}
	if(rt_src.Height() <= 0)
	{
		rt_src.top = 0;
		rt_src.bottom = img_info.cy;
	}
	rc.rr->DrawImage(rc.dc, img.image_name, &rt_src,
		rc.client_pos_on_client, &img.image_zoom_guardlines);
}


_SSUIL_END
_SSL_END
